#include <iostream>

using namespace std;

class A
{
public:
    A(int i) : data(i)
    {
        cout << "construct" << endl;
    }

    A(A& a)
    {
        data = a.data;
        cout << "copy construct" << endl;
    }

    A& operator=(const A& a) {
        data = a.data;
        cout << "assign" << endl;
        return *this;
    }

    A(A&& a)
    {
        data = a.data;
        cout << "move contruct" << endl;
    }

    int Get() const
    {
        return data;
    }
private:
    int data;
};

int GetData1(A a)
{
    return a.Get();
}

int GetData2(A& a)
{
    return a.Get();
}

int GetData3(A&& a)
{
    return a.Get();
}

A GetA1()
{
    A a(1);
    return a;
}

A GetA4()
{
    A a(4);
    return std::move(a);
}

// 局部变量不能返回引用，会出现段错误
A& GetA2()
{
    A a(2);
    return a;
}

// 无论时右值引用还是左值引用，本质上都是引用，所以当a超出作用域被析构后，引用为空
A&& GetA3()
{
    A a(3);
    return std::move(a);
}

void TestConstruct()
{
    A a1(1);
    A a2(a1);
    A a3 = a1;
    A a4 = 2;
    a3 = a4;

    int i = GetData1(a1);
    int j = GetData2(a2);
    int k = GetData3(3);
    cout << i << " " << j << " " << k << endl;

    A a5 = GetA1(); // 为什么没有调用移动构造函数或者拷贝构造函数，感觉a5直接使用了GetA1()函数中的a。
    // A a6 = GetA2();
    // A a7 = GetA3();
    A a8 = GetA4();
    a3 = GetA4();

    // cout << a5.Get() << endl;
}

int main()
{
    TestConstruct();
    return 0;
}
